home *** CD-ROM | disk | FTP | other *** search
- /**************************************************************
- Copyright 1990, 1991 Orion Network Systems, Inc. All Rights Reserved.
- **************************************************************/
- #include <Memory.h>
- #include <Resources.h>
- #include <Files.h>
- #include <Types.h>
- #include <Devices.h>
- #include <Events.h>
- #include <SysEqu.h> /* FOR PORTABLE BUG */
- #include <Strings.h>
- #include <Errors.h>
- #include <Notification.h>
- #include <OSUtils.h>
- #include <Folders.h>
-
- #include "init.h"
- #include "traceModule.h"
-
- pascal void InitMain()
- {
- short err;
- short refnum;
- StringPtr traceDrvrName;
- Handle dceHandle; /* FOR PORTABLE BUG */
- Handle drvrHandle; /* FOR PORTABLE BUG */
- Ptr entryPtr; /* FOR PORTABLE BUG */
- char myKeyMap[16];
- register short iconID = InactiveIconID;
- saveTypeHandle userPrefsHandle;
- short sysFolderRefNum=0;
- short prefsVolRef;
- Boolean shiftHeldDown;
- Boolean loadTraceDriver;
- SysEnvRec environment;
- Handle drvrName; // String pointer to target driver's name..
-
- err = SysEnvirons(1,&environment);
- if (err == noErr)
- sysFolderRefNum = environment.sysVRefNum;else sysFolderRefNum = 0; // Get the sys folder vref
-
- if (environment.systemVersion >= 0x0700)
- prefsVolRef = GetFolderVol(kPreferencesFolderType);
- else prefsVolRef = sysFolderRefNum;
-
- userPrefsHandle = GetUserPrefs(prefsVolRef, &drvrName);
-
- if (userPrefsHandle != nil)
- loadTraceDriver = ((**userPrefsHandle).fTraceOnStartup != 0);
- else loadTraceDriver = false;
-
- /* Check if the shift key is down - if it is then DO NOT install: */
- GetKeys((KeyMap) myKeyMap);
- shiftHeldDown = myKeyMap[shiftKeyCode / 8] & (0x01 << (shiftKeyCode % 8));
-
- if (shiftHeldDown)
- {
- // Driver will be installed when the cdev is first opened...
- iconID = InactiveIconID;
- }
- else
- {
-
- /* Install and open the driver */
-
- traceDrvrName = "\p.TRACE";
- err = InstallDriver(traceDrvrName);
-
- if (err == noErr)
- err = OpenDriver(traceDrvrName, &refnum);
-
- /* FOR PORTABLE BUG - after _Open on Mac portable, driver has been unlocked */
- /* on the system heap, even though dNeedLock is set in the driver flags !!! */
-
- if (err == noErr)
- {
- entryPtr = *((Ptr *) UTableBase);
- entryPtr += ((~refnum) * 4);
- dceHandle = *((Handle *) entryPtr);
- drvrHandle = (Handle) ((DCtlEntry *) *dceHandle)->dCtlDriver;
- if (drvrHandle != nil) /* Just in case */
- HLock(drvrHandle);
- if (loadTraceDriver)
- iconID = InvokeTrace(refnum, prefsVolRef, userPrefsHandle, drvrName);
- }
- else // Open Driver failed..
- {
- iconID = ErrorIconID;
- InitNotify(err,0); // Install STR Resource ID 0
- }
- DisposHandle((Handle) userPrefsHandle);
- }
- /* Display ShowINIT icon */
-
- ShowINIT(iconID, -1); /* Use moveX = -1 to move the default amount */
-
- return;
-
- }
-
- saveTypeHandle GetUserPrefs(short prefsVolRef, Handle *driverDotName)
- {
- register saveTypeHandle hSave = nil;
- short PrefsResRefNum;
- register short err;
- Handle PStrHand, targetAppName;
-
- *driverDotName = nil; // In case we don't get a chance to get the real one.
-
- PStrHand = GetResource('STR ', -4063); // Get name of Pref. file from within
- if (PStrHand != nil)
- {
- PrefsResRefNum = OpenRFPerm((const Str255)*PStrHand, prefsVolRef, fsRdWrPerm);
- err = ResError();
- ReleaseResource(PStrHand);
- if (err == noErr)
- {
- hSave = (saveTypeHandle) GetResource(kPrefResType, kPrefResID);
- if (hSave != nil)
- DetachResource((Handle)hSave); // Detach so we can close now...
-
- targetAppName = GetResource('kDRp', 128);
- if (targetAppName != nil)
- {
- *driverDotName = GetTargAppStuff(targetAppName);
- ReleaseResource(targetAppName);
- }
-
- CloseResFile(PrefsResRefNum);
- err = ResError();
- }
- }
- return hSave; // May be nil, as might *driverDotName
- }
-
- Handle GetTargAppStuff(Handle targetAppName)
- {
- short infoFileRefNum, err;
- Handle driverDotName = nil;
-
- if (targetAppName != nil)
- {
- HLock(targetAppName);
-
- infoFileRefNum = OpenRFPerm(*targetAppName, GetFolderVol(kSystemFolderType), fsRdWrPerm);
- if (infoFileRefNum == -1)
- infoFileRefNum = OpenRFPerm(*targetAppName, GetFolderVol(kExtensionFolderType), fsRdWrPerm);
- if (infoFileRefNum == -1)
- infoFileRefNum = OpenRFPerm(*targetAppName, GetFolderVol(kControlPanelFolderType), fsRdWrPerm);
- HUnlock(targetAppName);
- err = ResError();
- if (err == noErr)
- {
- // Get DotDriverName -- eg ".ASNA"
-
- driverDotName = GetResource('DrvN', 128);
- err = ResError();
- if (driverDotName != nil)
- {
- DetachResource(driverDotName);
- }
- else
- {
- // nil will be returned... which is okay
- }
-
- CloseResFile(infoFileRefNum);
- err = ResError();
- }
- }
- return driverDotName;
-
- }
-
- static void Append(char *pstr, char *addstr, short addlen)
- {
- register short plen;
-
- plen = *pstr;
-
- if ((addlen + plen) > 255)
- addlen = 255 - plen;
-
- BlockMove((char *) addstr, (char *) (pstr + plen + 1), addlen);
-
- *pstr += addlen;
-
- return;
-
- }
-
- void InitNotify(short err, short ResourceID)
- {
- NMRec *recPtr;
- char *errstr;
- register char *n;
- short numlen;
- Boolean showzero;
- char numstr[32];
- short dec, digit;
- short work;
- Handle strHandle;
- char *sub1;
- char *sub2;
- short sub1len;
- short sub2len;
-
-
- /* Allocate a record on the system heap to contain both the notification */
- /* manager record and the error string: */
-
- recPtr = (NMRec *) NewPtrSys(sizeof(NMRec) + 256);
-
- if (recPtr != (NMRec *) 0)
- {
-
- /* Generate a string containing the error code (signed): */
-
- n = numstr;
- numlen = 0;
- work = err;
- if (work < 0)
- {
- *n++ = '-';
- numlen++;
- work = (-work);
- }
- dec = 10000;
- showzero = false;
- while (dec > 0)
- {
- digit = work / dec;
- work = work % dec;
- if ((digit != 0) || showzero)
- {
- showzero = true;
- *n++ = digit + '0';
- numlen++;
- }
- if (dec > 1)
- dec = dec / 10;
- else
- dec = 0;
- }
-
- /* Get the string resource for the notification message ('STR '=0) */
- /* and copy it into the allocated memory, along with the error code */
- /* string. The error code string is inserted in the message string */
- /* where the first '%' character is found. */
-
- errstr = ((char *) recPtr) + sizeof(NMRec);
- *errstr = 0;
-
- strHandle = GetResource('STR ', ResourceID);
-
- if (strHandle != nil)
- {
-
- HLock(strHandle);
-
- /* Locate the '%' character, if any: */
-
- sub1 = (char *) *strHandle;
- sub2 = sub1;
- sub1len = *sub1++;
- sub2len = sub1len;
- if (sub1len > 0)
- sub2++;
-
- while ((*sub2 != '%') && (sub2len > 0))
- {
- sub2++;
- sub2len--;
- }
- if (sub2len > 0)
- {
- sub2++; /* move past '%' if found */
- sub2len--;
- sub1len -= sub2len;
- sub1len--;
- }
-
- /* Build the error string */
-
- Append(errstr, sub1, sub1len);
- Append(errstr, numstr, numlen);
- Append(errstr, sub2, sub2len);
-
- /* Release the string resource */
-
- ReleaseResource(strHandle);
-
- }
-
- /* See if there is an additional string resource for this error: */
-
- strHandle = GetResource('STR ', (-err)); /* Use absolute value of error */
-
- if (strHandle != nil)
- {
- HLock(strHandle);
-
- Append(errstr, (char *) ((*strHandle) + 1), **strHandle);
-
- ReleaseResource(strHandle);
-
- }
-
-
- /* Build the notification record and install it: */
- /* NOTE: The memory block will be left abandoned on the System Heap!!! */
-
- if (*errstr != 0)
- {
- recPtr->qType = (short) nmType;
- recPtr->nmMark = (short) 0;
- recPtr->nmIcon = (Handle) nil; // Formerly nmSIcon
- recPtr->nmSound = (Handle) -1;
- recPtr->nmStr = (StringPtr) errstr;
- recPtr->nmResp = (NMProcPtr) -1;
- recPtr->nmRefCon = (long) 0;
-
- (void) NMInstall(recPtr);
- }
- }
-
- return;
-
- }
-
- // These routines were taken from Tim Enwall's iacDriver in develop.
-
- /**********************************Comment*****************************************
- * lookForSlotInUnitTable returns a short corresponding to a valid "slot" number. It'll
- range from 48 to UnitNTryCnt. If there are no slots available it returns 0. Essentially what
- we're doing here is starting at the END of the UnitTable, testing the value at each
- long-word location to see if it's nil. If it's nil, that means we can place our driver
- at that location, so we'll return the value of the "slot".
- **********************************End Comment************************************/
- short
- lookForSlotInUnitTable()
- {
- short slot;
- Ptr theBass;
- long *theVoidPtr;
- Boolean foundSlot;
-
- slot = *((short *)(UnitNtryCnt)) - 1;
- theBass = (Ptr) (*((long *) (UTableBase)));
-
- foundSlot = false;
-
- while(slot>48 && !foundSlot)
- {
- theVoidPtr = (long *)(theBass + (4L * slot));
-
- if(*theVoidPtr == 0L)
- foundSlot = true;
-
- slot -= 1;
- }
-
- slot += 1;
-
- if(!foundSlot)
- slot = 0;
-
- return slot;
- }
-
-
- /**********************************Comment*****************************************
- * changeDRVRSlot installs the driver into the slot passed in. Because we want to keep
- * our DRVR resource ID in the resource file the same as it ever was, we GetResInfo on
- * it, and then set it back later. But, before we set it back, we set the ID of the
- * DRVR resource equal to the slot found, and then call OpenDriver. OpenDriver uses the
- * resource ID of the DRVR resource to place it in the UnitTable -- pretty easy huh?
- * The only other tricky thing is we have to Detach the resource by calling DetachResource
- * so the resource doesn't go away when the resource file gets closed (the Resource
- * Manager is our friend). The resource file gets closed when the INIT stops executing.
- **********************************End Comment************************************/
- short changeDRVRSlot(short slot, StringPtr name) /* Name is a pstring */
- {
- Handle theDRVR;
- short err, refNum;
- char DRVRname[256];
- short DRVRid;
- ResType DRVRType;
-
- if(slot != 0)
- {
- theDRVR = GetNamedResource('DRVR', name);
- if (theDRVR)
- {
- GetResInfo(theDRVR, &DRVRid, &DRVRType, &DRVRname);
- SetResInfo(theDRVR, slot, 0L);
-
- err = OpenDriver(name, &refNum);
- if(err == noErr)
- {
- /* detach the resources from the resource map */
- DetachResource(theDRVR);
-
- }
- /* Restores the previous resource attributes so they don't change
- * from startup to startup. We just want the in-memory copy to have
- * a different ID number -- not our resource in the file */
- theDRVR = GetNamedResource('DRVR', name);
- SetResInfo(theDRVR, DRVRid, nil);
- } else err = resNotFound;
- }
- return err;
- }
-
- /**********************************Comment*****************************************
- * InstallDriver installs a driver safely. Taken from iacDriver example.
- * it looks for a "slot" in the UnitTable into which the driver can be placed. If
- * it finds a "slot" it calls the procedure changeDRVRSlot to install the driver
- * into that slot.
- **********************************End Comment************************************/
-
- short InstallDriver(StringPtr drvrName)
- {
- short tsSlot;
- short err;
-
- if((tsSlot = lookForSlotInUnitTable()) != 0)
- err = changeDRVRSlot(tsSlot, drvrName);
- else err = unitTblFullErr;
-
- return err;
- }
-
- // Given open Tracks driver, this will start it using users preferences..
- short InvokeTrace(short TraceRefNum,short prefsFolderRefNum, saveTypeHandle hSave, Handle drvrName)
- {
- TraceParamBlock param;
- register short result, iconToUse;
- Boolean WarnOfAutoWrite = false;
- Handle PStrHand;
-
- iconToUse = TracingIconID;
- if (drvrName == nil)
- {
- return ErrorIconID;
- }
-
- PStrHand = GetResource('STR ', -4063);
- if (PStrHand == nil)
- {
- return ErrorIconID;
- }
-
- if ( (**hSave).Version != kVersionNumber) return ErrorIconID; // Version Error
- HLock((Handle)hSave);
-
- // **** Setup buffer area ****
- if ((**hSave).fBufferSize== nil)
- {
- InitNotify(smNilsBlockErr,2); // Couldn't allocate requested memory....
- return ErrorIconID;
- }
- param.u.enable.traceBuffSize = (**hSave).fBufferSize & 0x0000FFFe; /* Size of buffer (LIMITED TO 32K!) */
- param.u.enable.traceBuffSizeIndex = (**hSave).fCurrentSizeIndex; /* Points to correct value */
- result = Control(TraceRefNum, kEnableTraceBuffer, (Ptr) ¶m);
- if (result != noErr)
- {
- //InitNotify(result,2); // Couldn't allocate requested memory....
- return ErrorIconID;
- }
-
- // **** Handle File Name ****
- param.u.enableFile.fileName = (char *)*PStrHand;
- param.u.enableFile.vRefNum = prefsFolderRefNum; // Into sys folder
- result = Control(TraceRefNum, kSetTraceFileName, (Ptr) ¶m);
- if (result != noErr)
- {
- return ErrorIconID;
- }
-
- // **** Change Periodic write to file ****
- // This will set the dNeedTime bit.
- if ((**hSave).fAutoWriteOn)
- result = Control(TraceRefNum, kSetAutoWriteOn, nil);
- else
- result = Control(TraceRefNum, kSetAutoWriteOff, nil);
-
- if (result != noErr) iconToUse = ErrorIconID;
-
- result = Control(TraceRefNum,kStartedFromInit,(Ptr)true);
- if (result != noErr) iconToUse = ErrorIconID;
- // **** Set Break and Trace Masks ****
- BlockMove((Ptr)(**hSave).fBreakMask,(Ptr)param.u.mask.Mask,16L);
- param.u.mask.BreakOnce = (**hSave).fBreakOnceThenClear;
-
- result = Control(TraceRefNum, kGetCdevBreakMask, (Ptr) ¶m);
- if (result == noErr)
- BlockMove((Ptr)(**hSave).fTraceMask,(Ptr)param.u.mask.Mask,16L);
-
- result = Control(TraceRefNum, kGetCdevTraceMask, (Ptr) ¶m);
- if (result != noErr) iconToUse = ErrorIconID;
-
- // Turn Tracing On
-
- if ((**hSave).fTraceOnStartup && iconToUse != ErrorIconID)
- {
- result = Control(TraceRefNum, kSetTraceOnline, *drvrName);
- if (result == noErr && (**hSave).fAutoWriteOn)
- {InitNotify(1,1);} // Warn user that Auto Write to disk is on.
- if (result != noErr) iconToUse = ErrorIconID;
- }
- else if (iconToUse != ErrorIconID) iconToUse = InactiveIconID;
-
- HUnlock((Handle)hSave);
- DisposHandle((Handle)hSave);
- ReleaseResource(PStrHand);
- return (iconToUse);
- }
- // Returns vrefnum of a folder type
- short GetFolderVol(OSType type)
- {
- WDPBRec wdParamBlock; /*param block to set up working directory*/
- short result;
- short prefVRef;
- long prefDirID;
-
- result=FindFolder(kOnSystemDisk, type, true, &prefVRef, &prefDirID);
- if (result == 0)
- {
- wdParamBlock.ioCompletion = NULL;
- wdParamBlock.ioNamePtr = NULL;
- wdParamBlock.ioVRefNum = prefVRef;
- wdParamBlock.ioWDDirID = prefDirID;
- result=PBOpenWD(&wdParamBlock, false);
- if (result == 0)
- return wdParamBlock.ioVRefNum;
- }
- return 0;
- }
-